#!/bin/bash

#Decs:set lvs type of net
#author:zhang huan huan
#create:2020-09-11
#update:
#usage:

dip=
vip_port_str=
rip_ports=
dstype=
checkflag=false
ens33file=/etc/sysconfig/network-scripts/ifcfg-ens33

#校验输入时否是数字
checknum() {
	checkq $1
	echo $1 | egrep '[^0-9]'
	if [ $? -eq 0 ]; then
		echo "请输入正确的数字[0-9]"
		continue
	fi
}
#检测输入的q|Q退出程序
checkq() {
	if [ "$1" == 'Q' ] || [ "$1" == 'q' ]; then
		exit
	fi
}

#校验输入的ip是否合法，$2 false不验证ip是否存在 true 检查是否存
checkip() {
	checkq $1
	checkflag=false
	echo $1 | egrep "^([0-9]{1,3}\.){3}([0-9]{1,3})$" | grep -Ev "2[5-9][6-9]|[3-9][0-9]{2}"
	if [ $? -eq 0 ]; then
		if [ "$2" == "true" ]; then
			ping -c 3 $1 &>/dev/null
			if [ $? -eq 0 ]; then
				echo "ip：$1已经存在，退出检查配置或重新配置新的ip"
				continue
			fi
		fi
		checkflag=true
	else
		echo "请输入正确的ip（例127.0.0.1）"
		continue
	fi
}
#校验输入的ip:port是否合法 $2不验证ip是否存在
checkipport() {
	checkq $1
	checkflag=false
	count=$(echo $1 | awk -v RS=':' 'END{print --NR+1}')
	if [ $count -gt 2 ]; then
		echo "请输入正确的ip和端口（例127.0.0.1:80）"
		continue
	fi
	vipstr=$(echo $1 | awk -F ":" '{if($2<65535) print $1}')
	if [ $? -ne 0 ]; then
		echo "请输入正确的端口（0-65535）"
		continue
	fi
	checkip $vipstr $2
}

#设置vip $1 false 不检查ip是否存在 port 检查端口
setvip() {
	while [ "$checkflag" == "false" ]; do
		if [ "$1" == "port" ]; then
			read -p "请输入VIP和端口号：" vip_port_str
			checkipport $vip_port_str
		else
			read -p "请输入VIP：" vip_port_str
			checkip $vip_port_str $1
		fi
	done
}

#$1 false 不验证端口，true 验证端口
setreadip() {
	while [ "$checkflag" == "false" ]; do
		read -p "请输入read server数目:" num
		checknum $num
		for i in $(seq 1 $num); do
			checkflag=false
			while [ $checkflag == "false" ]; do
				if [ "$1" == "true" ]; then
					read -p "请输入第$i个read server ip和端口：" rip_ports[$i]
					checkipport ${rip_ports[$i]} "false"
				else
					read -p "请输入第$i个read server ip：" rip_ports[$i]
					checkip ${rip_ports[$i]} "false"
				fi
				checkflag=true
			done
		done
	done
}
#$1 m (net) g(dr)
install_ipvs() {
	#lc 最少连接，wlc加权最少连接，rr轮询，wrr 加权轮询
	read -p "请输入调度类型：" dstype
	checkq $dstype
	#install ipvsadm
	yum -y install ipvsadm

	if [ $1 == "g" ]; then
		ipvsadm -C
		vip_port_str=$vip_port_str:80
	fi
	#set virtual server
	ipvsadm -A -t $vip_port_str -s $dstype

	#add read server
	for i in $(seq 1 $num); do
		ipvsadm -a -t $vip_port_str -r ${rip_ports[$i]} -$1
	done
}
#net ds 设置
dsserverset() {
	setvip "port"
	checkflag=false
	setreadip "true"
	install_ipvs "m"

	#open net.ipv4.ip_forward=1
	grep -v "^$|^#" /etc/sysctl.conf | grep "net.ipv4.ip_forward" &>/dev/null
	if [ $? -eq 0 ]; then
		sed -i 's/net.ipv4.ip_forward.*/net.ipv4.ip_forward=1/' /etc/sysctl.conf
	else
		echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf
	fi
}

setgateway() {
	sed -i "s/GATEWAY.*/GATEWAY=$dip/" $ens33file
	echo "设置成功，正常重启网卡。。。"
	ifdown ens33
	ifup ens33
}
#net read server设置
readserverset() {
	while [[ $checkflag == "false" ]]; do
		displaychois
		read -p "请输入GATEWAY:" dip
		checkip $dip "false"
		case $choise in
		t | T)
			route del default
			route add default gw $dip
			;;
		p | P)
			setgateway
			;;
		esac
	done
}

displaychois() {
	choise=
	echo "t|T)暂时非永久"
	echo "p|P）永久"
	read -p "选择：" choise
	checkq $choise
	echo $choise | egrep "[tTpP]"
	if [ $? -ne 0 ]; then
		echo "请选择正确的选项"
		continue
	fi
	checkflag=true
}

#dr ds 配置
dr_serverset() {
	setvip
	checkflag=false
	setreadip "false"
	checkflag=false
	while [ $checkflag == "false" ]; do
		echo "配置vip"
		displaychois
		case $choise in
		"t|T")
			ifconfig ens33:0 $vip_port_str broadcast $vip_port_str netmask 255.255.255.255 up
			#可加可不加，老版本的系统要加
			route add -host $vip_port_str dev ens33:0
			;;
		"p|P")
			setgateway
			;;
		esac
	done
	install_ipvs "g"
}

#dr read 配置
dr_readset() {
	setvip "false"
	ifconfig lo:0 $vip_port_str broadcast $vip_port_str netmask 255.255.255.255 up
	#可加可不加，老版本的系统要加
	route add -host $vip_port_str dev lo:0

	while [ $checkflag == "false" ]; do
		echo "抑制RS服务器上的lo网卡的VIP响应ARP广播"
		displaychois
	done
	case $choise in
	t | T)
		echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
		echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
		echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
		echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
		;;
	p | P)
		cat >/etc/sysctl.conf <<EOF
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_announce=2
EOF
		sysctl -p
		;;
	esac
}

lvsnet() {
	chis=
	while :; do
		echo "---------------LVS-NET 模式设置---------------------------"
		echo "---------------d|D 设置director server-------------------"
		echo "---------------r|R 设置read     server-------------------"
		echo "---------------q|Q 退出----------------------------------"
		read -p "请输入：" chis
		case $chis in
		d | D)
			dsserverset
			break
			;;
		r | R)
			readserverset
			break
			;;
		q | Q)
			exit
			;;
		*)
			break
			;;
		esac
	done
}

lvsdr() {
	chis=
	while :; do
		echo "----------------LVSDR 模式设置----------------------------"
		echo "---------------d|D 设置director server-------------------"
		echo "---------------r|R 设置read     server-------------------"
		echo "---------------q|Q 退出----------------------------------"
		read -p "请输入：" chis
		case $chis in
		d | D)
			dr_serverset
			break
			;;
		r | R)
			dr_readset
			break
			;;
		q | Q)
			exit
			;;
		*)
			break
			;;
		esac
	done
}

while :; do
	echo "---------------LVS模式选择NET/DR--------------------------"
	echo "--------------------n|N)NET------------------------------"
	echo "--------------------d|D)DR--------------------------------"
	echo "--------------------q|Q 退出------------------------------"
	read -p "请输入：" chis
	case $chis in
	n | N)
		lvsnet
		break
		;;
	d | D)
		lvsdr
		break
		;;
	q | Q)
		exit
		;;
	*)
		break
		;;
	esac
done
